]> dgit.raspbian.org Git - gnome-shell.git/commitdiff
iconGrid/iconGrid: Wait for icon sizes before running spring animation
authorGeorges Basile Stavracas Neto <georges.stavracas@gmail.com>
Wed, 2 Dec 2020 20:43:13 +0000 (17:43 -0300)
committerMarge Bot <marge-bot@gnome.org>
Wed, 2 Dec 2020 22:43:04 +0000 (22:43 +0000)
To run the spring animation, IconGrid uses the transformed position and size
of the icons. This works okay when IconGridLayout doesn't need to update the
icon sizes, but looks bad when IconGridLayout selects a different icon size.

Wait for the icon sizes to be recalculated, and the icons  beallocated, before
running the spring animation. If no icon size update is pending, run the spring
animation directly.

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1518>

js/ui/iconGrid.js

index 093815922c49a8fafc45273a0e59f2eb1f927a1e..b7c8db5936d89239693aac154f3816bdeceb6bda 100644 (file)
@@ -391,6 +391,9 @@ var IconGridLayout = GObject.registerClass({
 
         this._containerDestroyedId = 0;
         this._updateIconSizesLaterId = 0;
+
+        this._resolveOnIdleId = 0;
+        this._iconSizeUpdateResolveCbs = [];
     }
 
     _findBestIconSize() {
@@ -701,11 +704,28 @@ var IconGridLayout = GObject.registerClass({
         return isRtl ? rowAlign * -1 : rowAlign;
     }
 
+    _runPostAllocation() {
+        if (this._iconSizeUpdateResolveCbs.length > 0 &&
+            this._resolveOnIdleId === 0) {
+            this._resolveOnIdleId = GLib.idle_add(GLib.PRIORITY_DEFAULT, () => {
+                this._iconSizeUpdateResolveCbs.forEach(cb => cb());
+                this._iconSizeUpdateResolveCbs = [];
+                this._resolveOnIdleId = 0;
+                return GLib.SOURCE_REMOVE;
+            });
+        }
+    }
+
     _onDestroy() {
         if (this._updateIconSizesLaterId >= 0) {
             Meta.later_remove(this._updateIconSizesLaterId);
             this._updateIconSizesLaterId = 0;
         }
+
+        if (this._resolveOnIdleId > 0) {
+            GLib.source_remove(this._resolveOnIdleId);
+            delete this._resolveOnIdleId;
+        }
     }
 
     vfunc_set_container(container) {
@@ -820,6 +840,8 @@ var IconGridLayout = GObject.registerClass({
         });
 
         this._pageSizeChanged = false;
+
+        this._runPostAllocation();
     }
 
     /**
@@ -964,6 +986,14 @@ var IconGridLayout = GObject.registerClass({
         return itemData.pageIndex;
     }
 
+    ensureIconSizeUpdated() {
+        if (this._updateIconSizesLaterId === 0)
+            return Promise.resolve();
+
+        return new Promise(
+            resolve => this._iconSizeUpdateResolveCbs.push(resolve));
+    }
+
     adaptToSize(pageWidth, pageHeight) {
         if (this._pageWidth === pageWidth && this._pageHeight === pageHeight)
             return;
@@ -1617,7 +1647,7 @@ var IconGrid = GObject.registerClass({
         this.layout_manager.adaptToSize(width, height);
     }
 
-    animateSpring(animationDirection, sourceActor) {
+    async animateSpring(animationDirection, sourceActor) {
         this._resetAnimationActors();
 
         let actors = this._getChildrenToAnimate();
@@ -1626,6 +1656,8 @@ var IconGrid = GObject.registerClass({
             return;
         }
 
+        await this.layout_manager.ensureIconSizeUpdated();
+
         let [sourceX, sourceY] = sourceActor.get_transformed_position();
         let [sourceWidth, sourceHeight] = sourceActor.get_size();
         // Get the center